package com.cygsunri.airCondition.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cygsunri.airCondition.entity.AirCache;
import com.cygsunri.airCondition.mapper.AirCacheMapper;
import com.cygsunri.airCondition.service.AirCacheService;
import com.cygsunri.common.constant.DataName;
import com.cygsunri.common.constant.DeviceType;
import com.cygsunri.common.service.CommonDataService;
import com.cygsunri.measurement.entity.Flag;
import com.cygsunri.measurement.entity.MeasurementValue;
import com.cygsunri.scada.base.BasePSR;
import com.cygsunri.scada.service.ScadaPSRService;
import com.cygsunri.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 */
@Slf4j
@Service
public class AirCacheServiceImpl extends ServiceImpl<AirCacheMapper, AirCache> implements AirCacheService {

    @Autowired
    private CommonDataService commonDataService;
    @Autowired
    private ScadaPSRService scadaPSRService;
    @Autowired
    private AirCacheMapper airCacheMapper;

    @Override
    @Transactional
    public void saveAirCache(AirCache airCache) {
        airCacheMapper.insert(airCache);
    }

    @Override
    public Double getAirCache(String psrID, String name, String date) {
        return airCacheMapper.getAirCache(psrID, name, date);
    }

    @Override
    public Double getAirCacheSum(String psrID, String name, String from, String to) {
        return airCacheMapper.getAirCacheSum(psrID, name, from, to);
    }

    @Override
    public void updateCache(String date) {
        long a = System.currentTimeMillis();
        List<BasePSR> subs = scadaPSRService.getDevicesByType(DeviceType.AIR_SUB.getKey());
        for (BasePSR sub : subs) {
            List<BasePSR> air_insides = scadaPSRService.getDeviceOfSubstationByType(sub.getId(), DeviceType.AIR_INSIDE.getKey());
            if (air_insides.isEmpty()) return;
            calcWorkTime(date, sub, air_insides);
        }
        log.info("日期：{}， 空调缓存耗时：{} ms", date, System.currentTimeMillis() - a);
    }

    @Override
    public void calcWorkTime(String date, BasePSR sub, List<BasePSR> air_insides) {
        for (BasePSR air_inside : air_insides) {
            calcWorkTime(date, sub, air_inside);
        }
    }

    /**
     * 计算每个空调使用时间缓存
     */
    private void calcWorkTime(String date, BasePSR sub, BasePSR air_inside) {
        List<MeasurementValue> list = commonDataService.getHistoryValue(air_inside.getId(), DataName.STATUS, DateUtil.startOfDay(date), DateUtil.endOfDay(date), 5, Flag.PERIOD, true);
        int lastPos1 = -1;//上次遍历到开的的位置
        int lastPos2 = -1;//上次遍历到关的的位置
        Double workTime = 0d;
        int i = 0;
        while (i < list.size()) {
            MeasurementValue m = list.get(i);
            if (m.isInValid()) {
                i++;
                continue;
            }
            if (m.getData() == 1) {
                if (lastPos1 == -1) {
                    lastPos1 = i;
                }
            }

            //找到关机时刻计算工作时间
                if (m.getData() == 0) {
                    lastPos2 = i;
                    if (lastPos1 >= 0) {
                        String onTime = list.get(lastPos1).getDate() + " " + list.get(lastPos1).getTime();
                        String offTime = list.get(lastPos2).getDate() + " " + list.get(lastPos2).getTime();
                        int time = DateUtil.getDurationMinutes(onTime, offTime);
                        workTime += (double) time / 60d;
                        lastPos1 = -1;
                    }
            }

            //判断隔夜一直开着的情况
            if (i == list.size() - 1 && lastPos1 >= 0) {
                String onTime = list.get(lastPos1).getDate() + " " + list.get(lastPos1).getTime();
                String offTime = list.get(list.size() - 1).getDate() + " " + list.get(list.size() - 1).getTime();
                int time = DateUtil.getDurationMinutes(onTime, offTime);
                workTime += (double) time / 60d;
            }
            i++;
        }
        AirCache airCache = new AirCache()
                .setDate(date)
                .setSubstation(sub.getId())
                .setPsrID(air_inside.getId())
                .setName(DataName.STATUS)
                .setData(workTime);
        saveAirCache(airCache);
    }

}
